// -*- mode: c++; indent-tabs-mode: nil; -*-
//
//The Biomolecule Toolkit (BTK) is a C++ library for use in the
//modeling, analysis, and design of biological macromolecules.
//Copyright (C) 2005-2006, Tim Robertson <kid50@users.sourceforge.net>,
//                         Chris Saunders <ctsa@users.sourceforge.net>
//
//This program is free software; you can redistribute it and/or modify
//it under the terms of the GNU Lesser General Public License as published
//by the Free Software Foundation; either version 2.1 of the License, or (at
//your option) any later version.
//
//This program is distributed in the hope that it will be useful,  but
//WITHOUT ANY WARRANTY; without even the implied warranty of'
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//Lesser General Public License for more details.
//
//You should have received a copy of the GNU Lesser General Public License
//along with this program; if not, write to the Free Software Foundation,
//Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

#include <btk/core/math/vector_math.hpp>

using namespace BTK::MATH;

BTKVector
BTK::MATH::
project_normal(BTKVector const & a,
               BTKVector const & b)
{
  BTKVector pr(b), out(a);
  normalize(pr);

  // pr is the projection of a onto r
  pr *= inner_prod(a,pr);

  // subtract the projection onto r from the original vector.
  // this yields the component normal to r.
  out -= pr;

  return out;
}

BTKVector
BTK::MATH::
project(BTKVector const & a,
        BTKVector const & b)
{
  BTKVector pr(b);
  normalize(pr);

  // pr is the projection of a onto r.
  pr *= inner_prod(a,pr);

  return pr;
}

// ctsa - note that this function used to be inlined, but it caused
// nasty core-dumps with g++ version 2.96 built w/ flags: -O2 -DNDEBUG
double
BTK::MATH::
vector_dihedral(BTKVector const & v1,
                BTKVector const & v2,
                BTKVector const & v3)
{
  // create a coordinate system where v2 is the z-axis.
  BTKVector yaxis = cross(v2,v1);
  BTKVector xaxis = cross(yaxis,v2);

  normalize(yaxis);
  normalize(xaxis);

  return atan2(prec_inner_prod(v3,yaxis),prec_inner_prod(v3,xaxis));
}
